package com.ruihu.admin.module.system.user;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruihu.admin.common.domain.PageResultDTO;
import com.ruihu.admin.common.domain.ResponseDTO;
import com.ruihu.admin.constant.CommonConst;
import com.ruihu.admin.module.system.department.dao.DepartmentDao;
import com.ruihu.admin.module.system.department.domain.entity.DepartmentEntity;
import com.ruihu.admin.module.system.login.domain.RequestTokenBO;
import com.ruihu.admin.module.system.position.PositionService;
import com.ruihu.admin.module.system.position.domain.dto.PositionRelationAddDTO;
import com.ruihu.admin.module.system.position.domain.dto.PositionRelationResultDTO;
import com.ruihu.admin.module.system.privilege.service.PrivilegeUserService;
import com.ruihu.admin.module.system.role.basic.RoleService;
import com.ruihu.admin.module.system.role.basic.domain.dto.RoleUserBatchDTO;
import com.ruihu.admin.module.system.role.basic.domain.dto.RoleVO;
import com.ruihu.admin.module.system.role.roleuser.RoleUserService;
import com.ruihu.admin.module.system.role.roleuser.domain.RoleUserDTO;
import com.ruihu.admin.module.system.systemconfig.SystemConfigService;
import com.ruihu.admin.module.system.systemconfig.constant.SystemConfigEnum;
import com.ruihu.admin.module.system.systemconfig.domain.dto.SystemConfigDTO;
import com.ruihu.admin.module.system.systemconfig.domain.dto.SystemConfigUpdateDTO;
import com.ruihu.admin.module.system.user.constant.UserResponseCodeConst;
import com.ruihu.admin.module.system.user.constant.UserStatusEnum;
import com.ruihu.admin.module.system.user.constant.UserTypeEnum;
import com.ruihu.admin.module.system.user.dao.UserDao;
import com.ruihu.admin.module.system.user.domain.bo.UserBO;
import com.ruihu.admin.module.system.user.domain.dto.*;
import com.ruihu.admin.module.system.user.domain.entity.UserEntity;
import com.ruihu.admin.module.system.user.domain.vo.UserVO;
import com.ruihu.admin.util.BeanCopierUtil;
import com.ruihu.admin.util.BeanUtil;
import com.ruihu.admin.util.DigestUtil;
import com.ruihu.admin.util.PageUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 员工管理
 *
 * @author lidoudou
 * @date 2017年12月21日上午11:54:52
 */
@Service
public class UserService {

    private static final String RESET_PASSWORD = "123456";

    @Autowired
    private UserDao userDao;

    @Autowired
    private DepartmentDao departmentDao;

    @Autowired
    private RoleUserService roleUserService;

    @Autowired
    private SystemConfigService systemConfigService;

    @Autowired
    private PositionService positionService;

    @Autowired
    private PrivilegeUserService privilegeUserService;

    @Autowired
    private RoleService roleService;

    /**
     * 用户基本信息的缓存
     */
    private static final ConcurrentHashMap<Long, UserBO> USER_CACHE = new ConcurrentHashMap<>();

    public List<UserVO> getAllUser() {
        return userDao.selectAll();
    }

    public List<UserDTO> getAllUser2() {
        return userDao.listAll();
    }

    public UserBO getById(Long id) {
        UserBO userBO = USER_CACHE.get(id);
        if (userBO == null) {
            UserEntity userEntity = userDao.selectById(id);
            if (userEntity != null) {
                Boolean superman = privilegeUserService.isSuperman(id);
                userBO = new UserBO(userEntity, superman);
                USER_CACHE.put(userEntity.getId(), userBO);
            }
        }
        return userBO;
    }

    /**
     * 根据用户姓名查询
     * @param userName
     * @return
     */
    public ResponseDTO<List<UserVO>> getUserListByName(String userName) {
        if (StrUtil.isNotEmpty(userName))
            userName = userName.trim();

        UserQueryDTO queryDTO = new UserQueryDTO();
        queryDTO.setName(userName);
        List<UserDTO> userDTOList = this.userDao.selectUserList(queryDTO);
        List<UserVO> userVOList = new ArrayList<>(userDTOList.size());
        for (UserDTO userDTO : userDTOList) {
            userVOList.add(BeanCopierUtil.copy(userDTO, UserVO.class));
        }
        return ResponseDTO.succData(userVOList);
    }

    /**
     * 查询员工列表
     *
     * @param queryDTO
     * @return
     */
    public PageResultDTO<UserVO> selectUserList(UserQueryDTO queryDTO) {
        Page pageParam = PageUtil.convert2QueryPage(queryDTO);
        List<UserDTO> UserList = userDao.selectUserList(pageParam, queryDTO);
        List<Long> userIdList = UserList.stream().map(UserDTO::getId).collect(Collectors.toList());
        List<RoleVO> roleVOS = roleService.getAllRole();
        Map<Long,String> rolesMap = roleVOS.stream().collect(Collectors.toMap(RoleVO::getId, RoleVO::getRoleName));
        if (CollectionUtils.isNotEmpty(userIdList)) {
            List<PositionRelationResultDTO> positionRelationResultDTOList = positionService.queryPositionByUsers(userIdList);
            Map<Long, List<PositionRelationResultDTO>> UserPositionMap = new HashedMap();
            for (PositionRelationResultDTO positionRelationResultDTO : positionRelationResultDTOList) {
                List<PositionRelationResultDTO> relationResultDTOList = UserPositionMap.get(positionRelationResultDTO.getUserId());
                //匹配对应的岗位
                if (relationResultDTOList == null) {
                    relationResultDTOList = new ArrayList<>();
                    UserPositionMap.put(positionRelationResultDTO.getUserId(), relationResultDTOList);
                }
                relationResultDTOList.add(positionRelationResultDTO);
            }

            for (UserDTO userDTO : UserList) {
                List<PositionRelationResultDTO> relationResultDTOList = UserPositionMap.get(userDTO.getId());
                if (relationResultDTOList != null) {
                    userDTO.setPositionRelationList(relationResultDTOList);
                    userDTO.setPositionName(relationResultDTOList.stream().map(PositionRelationResultDTO::getPositionName).collect(Collectors.joining(",")));
                }
                String roleIds = userDTO.getRoleIds();
                if (StringUtils.isNotEmpty(roleIds)) {
                    List<Long> roleList = Arrays.asList(roleIds.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
                    StringBuilder roleName = new StringBuilder();
                    for(Long role:roleList){
                        if(roleName.length()>0){
                            roleName.append(",");
                        }
                        if(MapUtils.isNotEmpty(rolesMap)&&rolesMap.containsKey(role)){
                            roleName.append(rolesMap.get(role));
                        }
                    }
                    userDTO.setRoleNames(roleName.toString());
                }

            }
        }
        return PageUtil.convert2PageResult(pageParam, UserList.stream().map(this::buildUser).collect(Collectors.toList()));
    }

    private UserVO buildUser(UserDTO dto) {
        if (dto == null) {
            return null;
        }
        UserVO userVO = new UserVO();
        userVO.setId(dto.getId());
        userVO.setUsername(dto.getUsername());
        userVO.setWorkNo(dto.getWorkNo());
        userVO.setUserType(dto.getUserType());
        userVO.setUserTypeName(UserTypeEnum.getByCode(dto.getUserType()).getDesc());
        userVO.setNickName(dto.getNickName());
        userVO.setActualName(dto.getActualName());
        userVO.setRoleName(dto.getRoleNames());
        userVO.setPhone(dto.getPhone());
        userVO.setIdCard(dto.getIdCard());
        userVO.setBirthday(dto.getBirthday());
        userVO.setCreateUser(dto.getCreateUser());
        userVO.setDepartmentId(dto.getDepartmentId());
        userVO.setIsLeave(dto.getIsLeave());
        userVO.setIsDisabled(dto.getIsDisabled());
        userVO.setIsDelete(dto.getIsDelete());
        userVO.setDepartmentName(dto.getDepartmentName());
        userVO.setEmail(dto.getEmail());
        userVO.setCreateTime(dto.getCreateTime());
        userVO.setPositionRelationList(dto.getPositionRelationList());
        userVO.setPositionName(dto.getPositionName());
        userVO.setOrgId(dto.getOrgId());
        userVO.setOrgName(dto.getOrgName());
        return userVO;
    }


    private UserVO buildUser(UserEntity entity) {
        if (entity == null) {
            return null;
        }
        UserVO userVO = new UserVO();
        userVO.setId(entity.getId());
        userVO.setUsername(entity.getUsername());
        userVO.setWorkNo(entity.getWorkNo());
        userVO.setUserType(entity.getUserType());
        userVO.setNickName(entity.getNickName());
        userVO.setActualName(entity.getActualName());
        userVO.setPhone(entity.getPhone());
        //目前只能设置角色用户一对一
        List<Long> roles = roleUserService.queryRolesByUserId(entity.getId());
        if(CollectionUtils.isNotEmpty(roles)&&roles.size()==1){
            userVO.setRoleId(roles.get(0));
        }
        userVO.setDepartmentId(entity.getDepartmentId());
        userVO.setEmail(entity.getEmail());
        DepartmentEntity departmentEntity = departmentDao.selectById(entity.getDepartmentId());
        userVO.setOrgId(departmentEntity==null?null:departmentEntity.getOrgId());
        List<PositionRelationResultDTO> positionRelationResultDTOList = positionService.queryPositionByUserId(entity.getId());
        userVO.setRemark(entity.getRemark());
        userVO.setPositionRelationList(positionRelationResultDTOList);
        return userVO;
    }

    public UserVO queryByUserId(Long userId) {
        if(userId==null){
            return null;
        }
        return buildUser(userDao.selectById(userId));
    }

    /**
     * 新增员工
     *
     * @param userAddDto
     * @param requestToken
     * @return
     */
    public ResponseDTO<String> addUser(UserAddDTO userAddDto, RequestTokenBO requestToken) {
        UserEntity entity = BeanCopierUtil.copy(userAddDto, UserEntity.class);
        //同名员工
        UserDTO sameNameUser = userDao.getByUsername(entity.getUsername(),UserStatusEnum.NORMAL.getValue());
        if (null != sameNameUser) {
            return ResponseDTO.wrap(UserResponseCodeConst.USERNAME_EXISTS);
        }
        //同电话员工
        UserDTO samePhoneUser = userDao.getByPhone(entity.getPhone(), UserStatusEnum.NORMAL.getValue());
        if (null != samePhoneUser) {
            return ResponseDTO.wrap(UserResponseCodeConst.PHONE_EXISTS);
        }
        Long departmentId = entity.getDepartmentId();
        DepartmentEntity department = departmentDao.selectById(departmentId);
        if (department == null) {
            return ResponseDTO.wrap(UserResponseCodeConst.DEPT_NOT_EXIST);
        }
        //如果没有密码  默认设置为123456
        String pwd = entity.getPassword();
        if(!Objects.equals(userAddDto.getPassword(),userAddDto.getPasswordAgain())){
            return ResponseDTO.wrap(UserResponseCodeConst.PASSWORD_NOT_MATCH);
        }
        if (StringUtils.isBlank(pwd)) {
            entity.setPassword(DigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, RESET_PASSWORD));
        } else {
            entity.setPassword(DigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, entity.getPassword()));
        }
        if (Objects.nonNull(requestToken))
            entity.setCreateUser(requestToken.getRequestUserId());
        else
            entity.setCreateUser(0L);
        if (StringUtils.isEmpty(entity.getBirthday())) {
            entity.setBirthday(null);
        }
        userDao.insert(entity);
        //若角色id不为空写入角色表
        if(userAddDto.getRoleId()!=null){
            RoleUserDTO roleUserDTO = new RoleUserDTO();
            roleUserDTO.setUserId(entity.getId());
            roleUserDTO.setRoleId(userAddDto.getRoleId());
            roleUserService.insertUserRole(roleUserDTO);
        }

        //如果是超级管理员则新增配置表
        if(Objects.equals(UserTypeEnum.SUPER_ADMIN.getValue(),entity.getUserType())){
            List<String> superUsers = new ArrayList<>();
            SystemConfigDTO systemConfig = systemConfigService.getCacheByKey(SystemConfigEnum.Key.USER_SUPERMAN);
            if(Objects.nonNull(systemConfig)){
                if(StringUtils.isNotEmpty(systemConfig.getConfigValue())){
                    superUsers = new ArrayList<>(Arrays.asList(systemConfig.getConfigValue().split(",")));
                }
                superUsers.add(String.valueOf(entity.getId()));
                updateSuperUser(systemConfig,StringUtils.join(superUsers,","));
            }
        }
        //保存岗位信息
        if(CollectionUtils.isNotEmpty(userAddDto.getPositionIdList())){
            PositionRelationAddDTO positionRelAddDTO = new PositionRelationAddDTO(userAddDto.getPositionIdList(), entity.getId());
            positionService.addPositionRelation(positionRelAddDTO);
        }
        return ResponseDTO.succ();
    }

    /**
     * 新增员工
     *
     * @param userAddDto
     * @param requestToken
     * @return
     */
    public ResponseDTO<String> addUserSimple(UserAddDTO userAddDto, RequestTokenBO requestToken) {
        UserEntity entity = BeanCopierUtil.copy(userAddDto, UserEntity.class);
        Long departmentId = entity.getDepartmentId();
        DepartmentEntity department = departmentDao.selectById(departmentId);
        //如果没有密码  默认设置为123456
        String pwd = entity.getPassword();
        if(!Objects.equals(userAddDto.getPassword(),userAddDto.getPasswordAgain())){
            return ResponseDTO.wrap(UserResponseCodeConst.PASSWORD_NOT_MATCH);
        }
        if (StringUtils.isBlank(pwd)) {
            entity.setPassword(DigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, RESET_PASSWORD));
        } else {
            entity.setPassword(DigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, entity.getPassword()));
        }
        if (Objects.nonNull(requestToken))
            entity.setCreateUser(requestToken.getRequestUserId());
        else
            entity.setCreateUser(0L);
        if (StringUtils.isEmpty(entity.getBirthday())) {
            entity.setBirthday(null);
        }
        userDao.insert(entity);
        //若角色id不为空写入角色表
        if(userAddDto.getRoleId()!=null){
            RoleUserDTO roleUserDTO = new RoleUserDTO();
            roleUserDTO.setUserId(entity.getId());
            roleUserDTO.setRoleId(userAddDto.getRoleId());
            roleUserService.insertUserRole(roleUserDTO);
        }
        return ResponseDTO.succ();
    }

    /**
     * 更新禁用状态
     *
     * @param userId
     * @param status
     * @return
     */
    public void updateStatus(Long userId, Integer status) {
        UserEntity userEntity = new UserEntity();
        userEntity.setId(userId);
        userEntity.setIsDisabled(status);
        userDao.updateById(userEntity);
        USER_CACHE.remove(userId);
    }

    /**
     * 批量更新员工状态
     *
     * @param batchUpdateStatusDTO
     * @return
     */
    public void batchUpdateStatus(UserBatchUpdateStatusDTO batchUpdateStatusDTO) {
        userDao.batchUpdateStatus(batchUpdateStatusDTO.getUserIds(), batchUpdateStatusDTO.getStatus());
        if (batchUpdateStatusDTO.getUserIds() != null) {
            batchUpdateStatusDTO.getUserIds().forEach(e -> USER_CACHE.remove(e));
        }
    }

    /**
     * 更新员工
     *
     * @param updateDTO
     * @return
     */
    public ResponseDTO<String> updateUser(UserUpdateDTO updateDTO) {
        Long userId = updateDTO.getId();
        UserEntity userEntity = userDao.selectById(userId);
        if (null == userEntity) {
            return ResponseDTO.wrap(UserResponseCodeConst.USER_NOT_EXISTS);
        }
        /*if(!Objects.equals(updateDTO.getPassword(),updateDTO.getPasswordAgain())){
            return ResponseDTO.wrap(UserResponseCodeConst.PASSWORD_NOT_MATCH);
        }*/
        Long departmentId = updateDTO.getDepartmentId();
        DepartmentEntity departmentEntity = departmentDao.selectById(departmentId);
        if (departmentEntity == null) {
            return ResponseDTO.wrap(UserResponseCodeConst.DEPT_NOT_EXIST);
        }
        Long roleId = updateDTO.getRoleId();
        //若角色id不为空写入角色表
        if(roleId!=null){
            //先删除角色
            roleUserService.removeRolesByUserId(userId);
            //后插入
            RoleUserDTO roleUserDTO = new RoleUserDTO();
            roleUserDTO.setUserId(updateDTO.getId());
            roleUserDTO.setRoleId(roleId);
            roleUserService.insertUserRole(roleUserDTO);
        }
        //用户名
        UserDTO sameNameUser = userDao.getByUsername(updateDTO.getUsername(), UserStatusEnum.NORMAL.getValue());
        if (null != sameNameUser && !sameNameUser.getId().equals(userId)) {
            return ResponseDTO.wrap(UserResponseCodeConst.USERNAME_EXISTS);
        }
        //手机号
        UserDTO samePhoneUser = userDao.getByPhone(updateDTO.getPhone(), UserStatusEnum.NORMAL.getValue());
        if (null != samePhoneUser && !samePhoneUser.getId().equals(userId)) {
            return ResponseDTO.wrap(UserResponseCodeConst.PHONE_EXISTS);
        }
        //密码
        /*String newPwd = updateDTO.getPassword();
        if (!StringUtils.isBlank(newPwd)) {
            updateDTO.setPassword(DigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, updateDTO.getPassword()));
        } else {
            updateDTO.setPassword(userEntity.getPassword());
        }*/
        UserEntity entity = BeanUtil.copy(updateDTO, UserEntity.class);
        entity.setUpdateTime(new Date());
        if (CollectionUtils.isNotEmpty(updateDTO.getPositionIdList())) {
            //删除旧的关联关系 添加新的关联关系
            positionService.removePositionRelation(userId);
            PositionRelationAddDTO positionRelAddDTO = new PositionRelationAddDTO(updateDTO.getPositionIdList(), entity.getId());
            positionService.addPositionRelation(positionRelAddDTO);
        }
        List<String> superUsers = new ArrayList<>();
        SystemConfigDTO systemConfig = systemConfigService.getCacheByKey(SystemConfigEnum.Key.USER_SUPERMAN);
        if(Objects.nonNull(systemConfig)){
            if(StringUtils.isNotEmpty(systemConfig.getConfigValue())){
                superUsers =  new ArrayList<>(Arrays.asList(systemConfig.getConfigValue().split(",")));
            }
        }
        if(Objects.equals(UserTypeEnum.SUPER_ADMIN.getValue(),entity.getUserType())){
            //选择超管跟查询后的用户类型不一致
            if(!Objects.equals(UserTypeEnum.SUPER_ADMIN.getValue(),userEntity.getUserType())){
                superUsers.add(String.valueOf(userId));
                updateSuperUser(systemConfig,StringUtils.join(superUsers,","));
            }
        }else{
            if(Objects.equals(UserTypeEnum.SUPER_ADMIN.getValue(),userEntity.getUserType())){
                superUsers.remove(String.valueOf(userId));
                updateSuperUser(systemConfig,StringUtils.join(superUsers,","));
            }
        }
        userDao.updateById(entity);
        USER_CACHE.remove(userId);
        return ResponseDTO.succ();
    }

    public ResponseDTO<String> updateUserSimple(UserUpdateDTO userUpdateDTO) {
        UserEntity entity = BeanCopierUtil.copy(userUpdateDTO, UserEntity.class);
        userDao.updateById(entity);
        USER_CACHE.remove(userUpdateDTO.getId());
        return ResponseDTO.succ();
    }

    private void updateSuperUser(SystemConfigDTO systemConfig,String configValue){
        SystemConfigUpdateDTO systemConfigUpdateDTO = new SystemConfigUpdateDTO();
        systemConfigUpdateDTO.setConfigKey(systemConfig.getConfigKey());
        systemConfigUpdateDTO.setId(systemConfig.getId());
        systemConfigUpdateDTO.setConfigValue(configValue);
        systemConfigService.updateSystemConfig(systemConfigUpdateDTO);
    }

    /**
     * 删除员工
     *
     * @param userId 用户ID
     * @return
     */
    public ResponseDTO<String> deleteUserById(Long userId) {
        UserEntity userEntity = userDao.selectById(userId);
        if (null == userEntity) {
            return ResponseDTO.wrap(UserResponseCodeConst.USER_NOT_EXISTS);
        }
        userDao.deleteById(userId);
        USER_CACHE.remove(userId);
        return ResponseDTO.succ();
    }

    /**
     * 更新用户角色
     *
     * @param updateRolesDTO
     * @return
     */
    public void updateRoles(UserUpdateRolesDTO updateRolesDTO) {
        roleUserService.deleteByUserId(updateRolesDTO.getUserId());
        if (CollectionUtils.isNotEmpty(updateRolesDTO.getRoleIds())) {
            roleUserService.batchAddUserRole(RoleUserBatchDTO.builder().roleIds(updateRolesDTO.getRoleIds())
                    .userId(updateRolesDTO.getUserId()).build());
        }
    }

    /**
     * 更新密码
     *
     * @param updatePwdDTO
     * @param requestToken
     * @return
     */
    public ResponseDTO<String> updatePwd(UserUpdatePwdDTO updatePwdDTO, RequestTokenBO requestToken) {
        Long UserId = requestToken.getRequestUserId();
        UserEntity User = userDao.selectById(UserId);
        if (User == null) {
            return ResponseDTO.wrap(UserResponseCodeConst.USER_NOT_EXISTS);
        }
        if (!User.getPassword().equals(DigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, updatePwdDTO.getOldPwd()))) {
            return ResponseDTO.wrap(UserResponseCodeConst.PASSWORD_ERROR);
        }
        User.setPassword(DigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, updatePwdDTO.getPwd()));
        userDao.updateById(User);
        USER_CACHE.remove(UserId);
        return ResponseDTO.succ();
    }

    public ResponseDTO<List<UserVO>> getUserByDeptId(Long departmentId) {
        List<UserVO> list = userDao.getUserIdByDeptId(departmentId);
        return ResponseDTO.succData(list);
    }

    /**
     * 重置密码
     *
     * @param userId
     * @return
     */
    public ResponseDTO resetPasswd(Integer userId) {
        String md5Password = DigestUtil.encryptPassword(CommonConst.Password.SALT_FORMAT, RESET_PASSWORD);
        userDao.updatePassword(userId, md5Password);
        USER_CACHE.remove(userId);
        return ResponseDTO.succ();
    }
}
